package edu.tfh.s2.ehkbot.daten.simulation;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Vector;

import edu.tfh.s2.ehkbot.daten.Protokoll;
import edu.tfh.s2.ehkbot.daten.PrototypFactory;

import edu.tfh.s2.ehkbot.daten.InitFactory.InitFactoryState;
import edu.tfh.s2.ehkbot.daten.Zeitgeber.ZeitgeberState;
import edu.tfh.s2.ehkbot.gerete.aktoren.BiStateAktor;
import edu.tfh.s2.ehkbot.gerete.aktoren.MotorAktor;
import edu.tfh.s2.ehkbot.gerete.aktoren.simulation.BiStateAktorSimulation;
import edu.tfh.s2.ehkbot.gerete.aktoren.simulation.MotorAktorAktiviereStateSimulation;
import edu.tfh.s2.ehkbot.gerete.aktoren.simulation.MotorAktorDeaktiviereBlockiertStateSimulation;
import edu.tfh.s2.ehkbot.gerete.sensoren.BarcodeScanner;
import edu.tfh.s2.ehkbot.gerete.sensoren.Kamera;
import edu.tfh.s2.ehkbot.gerete.sensoren.Sensor;
import edu.tfh.s2.ehkbot.gerete.sensoren.IndoorGPS.IndoorGPSState;
import edu.tfh.s2.ehkbot.gerete.sensoren.simulation.SensorStateSimulation;
import edu.tfh.s2.ehkbot.inventar.Warenbestand;
import edu.tfh.s2.ehkbot.inventar.WarenboxRegal;
import edu.tfh.s2.ehkbot.simulation.SimulationGUI;
import edu.tfh.s2.ehkbot.steuerung.BusAdresse;
import edu.tfh.s2.ehkbot.steuerung.Karte;
import edu.tfh.s2.ehkbot.steuerung.schnittstellen.Netzwerk.NetzwerkState;

/**
 * State für die InitFactory welches für den Zustands Simulation zuständig ist.
 * 
 * @author s2zehn
 */
public class InitFactorySimulation implements InitFactoryState {

	private IndoorGPSState indoorGPS;
	private File kartenDatei;
	private PrototypFactory prototypFactory;

	/**
	 * Konstruktor für die InitFactorySimulation.
	 * 
	 * @param kartenDatei
	 *            File Objekt welches eine Datei angibt die eine Karte enthält.
	 * @param prototypFactory
	 *            Eine Hilfs PrototypFactory um Clonbare Objekte zu erzeugen.
	 * @param indoorGPS
	 *            Das IndoorGPSSate
	 */
	public InitFactorySimulation(File kartenDatei, PrototypFactory prototypFactory, IndoorGPSState indoorGPS) {
		super();

		this.kartenDatei = kartenDatei;
		this.prototypFactory = prototypFactory;
		this.indoorGPS = indoorGPS;
	}

	/**
	 * @see edu.tfh.s2.ehkbot.daten.InitFactory.InitFactoryState#getBarcodeScanner()
	 */
	@Override
	public BarcodeScanner getBarcodeScanner() {
		return prototypFactory.getBarcodeScanner();
	}

	/**
	 * @see edu.tfh.s2.ehkbot.daten.InitFactory.InitFactoryState#getBiStateAktor(edu.tfh.s2.ehkbot.steuerung.BusAdresse)
	 */
	@Override
	public BiStateAktor getBiStateAktor(BusAdresse busAdresse) {
		return new BiStateAktor(busAdresse, new BiStateAktorSimulation());
	}

	/**
	 * @see edu.tfh.s2.ehkbot.daten.InitFactory.InitFactoryState#getIndoorGPS()
	 */
	@Override
	public IndoorGPSState getIndoorGPS() {
		return indoorGPS;
	}

	/**
	 * @see edu.tfh.s2.ehkbot.daten.InitFactory.InitFactoryState#getKamera()
	 */
	@Override
	public Kamera getKamera() {
		return prototypFactory.getKamera();
	}

	/**
	 * @see edu.tfh.s2.ehkbot.daten.InitFactory.InitFactoryState#getKarte()
	 */
	@Override
	public Karte getKarte() {
		int[][] karte = null;
		Vector<Vector<Integer>> lines = new Vector<Vector<Integer>>();

		try {
			BufferedReader buffer = new BufferedReader(new FileReader(kartenDatei));
			while (buffer.ready()) {
				String line = buffer.readLine();
				String[] cols = line.split("\\t");
				Vector<Integer> row = new Vector<Integer>();

				for (int i = 0; i < cols.length; ++i) {
					row.add(Integer.valueOf(cols[i]));
				}
				lines.add(row);
			}

			karte = new int[lines.size()][lines.firstElement().size()];
			for (int r = 0; r < lines.size(); ++r) {
				for (int c = 0; c < lines.firstElement().size(); ++c) {
					karte[r][c] = lines.get(r).get(c);
				}
			}
		} catch (IOException e) {
			Protokoll.getInstanc().exception(e);
		}
		Karte.Toplogie[][] topo = new Karte.Toplogie[karte.length][karte[0].length];
		for (int y = 0; y < topo.length; ++y) {
			for (int x = 0; x < topo[0].length; ++x) {
				if (karte[y][x] == 255)
					topo[y][x] = Karte.Toplogie.FAHRBEREICH;
				else
					topo[y][x] = Karte.Toplogie.REGAL;
			}
		}
		return new Karte(topo);
	}

	/**
	 * @see edu.tfh.s2.ehkbot.daten.InitFactory.InitFactoryState#getMotorAktor(edu.tfh.s2.ehkbot.steuerung.BusAdresse)
	 */
	@Override
	public MotorAktor getMotorAktor(BusAdresse busAdr) {
		MotorAktor motorAktor = new MotorAktor(
			busAdr,
			new MotorAktorAktiviereStateSimulation(),
			new MotorAktorDeaktiviereBlockiertStateSimulation());
		return motorAktor;
	}

	/**
	 * @see edu.tfh.s2.ehkbot.daten.InitFactory.InitFactoryState#getNetzwerk()
	 */
	@Override
	public NetzwerkState getNetzwerk() {
		return prototypFactory.getNetzwerk();
	}

	/**
	 * @see edu.tfh.s2.ehkbot.daten.InitFactory.InitFactoryState#getSensor(edu.tfh.s2.ehkbot.steuerung.BusAdresse)
	 */
	@Override
	public Sensor getSensor(BusAdresse busAdr) {
		return new Sensor(busAdr, new SensorStateSimulation());
	}

	/**
	 * @see edu.tfh.s2.ehkbot.daten.InitFactory.InitFactoryState#getWarenbestand()
	 */
	@Override
	public Warenbestand getWarenbestand() {
		return SimulationGUI.getInstance().getWarenbestand();
	}

	/**
	 * @see edu.tfh.s2.ehkbot.daten.InitFactory.InitFactoryState#getWarenboxregal()
	 */
	@Override
	public WarenboxRegal getWarenboxregal() {
		return SimulationGUI.getInstance().getWarenboxregal();
	}

	/**
	 * @see edu.tfh.s2.ehkbot.daten.InitFactory.InitFactoryState#getZeitgeber()
	 */
	@Override
	public ZeitgeberState getZeitgeber() {
		return prototypFactory.getZeitgeber();
	}
}
